package ru.cannabis.command.base;

import com.google.gson.Gson;
import ru.cannabis.command.params.JSONEmptyParams;
import ru.cannabis.command.response.base.JSONResponse;
import org.apache.mina.core.session.IoSession;

import java.lang.reflect.ParameterizedType;

abstract public class AbstractCommand<T extends JSONEmptyParams, S extends JSONResponse> {

	private IoSession session;
	private String name;
	private T params;
	private S response;   ////

    ///// TODO FUCK MONICA BELUCCI


	protected abstract boolean checkAccess();

	public void setName(String name) {
		this.name = name;
	}

	public String getName() {
		return name;
	}

	public void setSession(IoSession session) {
		this.session = session;
	}

	public IoSession getSession() {
		return session;
	}

	@Deprecated
	public boolean init() {
		return true;
	}

	public final void initParams(String jsonString) {
		if (getParameterClass() != null) {
			Gson converter = new Gson();

			setParameterObject(converter.fromJson(jsonString, getParameterClass()));
		}
	}

	public S getResponse() {
		return response;
	}

	public void run() {
		try {
			this.response = getResponseClass().newInstance();
		} catch (InstantiationException e) {
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			e.printStackTrace();
		}


		if (checkAccess()) {
			innerRun(this.response);
		} else {
			this.response.setResult(false);
		}
	}

	abstract public void innerRun(S response);

	private Class<? extends T> getParameterClass() {
		return ((Class) ((ParameterizedType) this.getClass().getGenericSuperclass()).getActualTypeArguments()[0]);
	}

	private Class<? extends S> getResponseClass() {
		return ((Class) ((ParameterizedType) this.getClass().getGenericSuperclass()).getActualTypeArguments()[1]);
	}


	private void setParameterObject(T params) {
		this.params = params;
	}

	public T getParams() {
		return params;
	}

	/*protected void setResponse(S response) {
		this.response = response;
	}*/
}
